import json
from datetime import datetime
from typing import Optional, Callable, Any

from pydantic import Field, BaseModel


class CarA(BaseModel):
    name: Optional[str] = Field()
    age: Optional[int] = Field(default=0)


class CarB(BaseModel):
    name: Optional[str] = Field()
    address: Optional[str] = Field(default='')
    birthday: Optional[datetime] = Field(default=datetime.now())

class CarC():
    name: str
    address: str
    birthday: datetime
    gender: int
    def __init__(self, name, address, birthday, gender=0) -> None:
        self.name = name
        self.address = address
        self.birthday = birthday
        self.gender = gender

    # 需要实现该方法才可以序列化
    def __iter__(self):
        yield from [(k, v) for (k, v) in self.__dict__.items() if not k.startswith('_')]


def objconvert(obj, cls):
    """
    对象转换
    :rtype: object
    """
    return cls(**dict(obj))


now = datetime.now()
a = CarA(name="小米")
print(f"car a json: {a.json()}  jsontype: {type(a.json())}")

b = objconvert(a, CarB)
print(f"car b json: {b.json()}")

print(f"判断类型datetime：{type(datetime.now()) == datetime}")

encoder_map = {
    datetime: lambda obj: obj.strftime("%Y-%m-%d")
}

print(f"encoder_map匹配格式化：{encoder_map.get(type(now))(now)}")



class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        return super().default(obj)

class CustomDecoder(json.JSONDecoder):
    convert_field = ["birthday"]

    def __init__(self, *args, **kwargs):
        super().__init__(object_hook=self.dict_to_json, *args, **kwargs)

    def dict_to_json(self, json_dict):
        for key in json_dict:
            if key in CustomDecoder.convert_field:
                json_dict[key] = datetime.strptime(str(json_dict[key])[0:10], "%Y-%m-%d")
        return json_dict

print(f"=======    json序列号和反序列化     ========")

b_json_str=json.dumps(dict(b), ensure_ascii=False, cls=CustomEncoder)
print(f"序列化后 类型：{type(b_json_str)}  数据：{b_json_str}")

b_json_obj=json.loads(b_json_str, cls=CustomDecoder)
print(f"反序列化后 类型：{type(b_json_obj)}  数据：{b_json_obj}")

b_obj = CarB(**b_json_obj)
print(f"反序列化后实例化对象 类型：{type(b_obj)}  数据：{b_obj}")

c_obj1 = CarC(**b_json_obj)
print(f"实例化对象c 类型：{type(c_obj1)}  数据：{dict(c_obj1)}")

c_obj2 = objconvert(b_obj, CarC)
print(f"对象转换c 类型：{type(c_obj2)}  数据：{dict(c_obj2)}")